home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Tool Chest / Dev.CD Feb 97 TC.toast / Sample Code / Development Tools & Languages / AppsToGo / pbClock / ButtonsControl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  7.5 KB  |  352 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         buttonscontrol.c
  5. ** Written by:      Eric Soldan
  6. **
  7. ** Copyright © 1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #ifndef __CONTROLS__
  26. #include <Controls.h>
  27. #endif
  28.  
  29. #ifndef __ERRORS__
  30. #include <Errors.h>
  31. #endif
  32.  
  33. #ifndef __FONTS__
  34. #include <Fonts.h>
  35. #endif
  36.  
  37. #ifndef __MEMORY__
  38. #include <Memory.h>
  39. #endif
  40.  
  41. #ifndef __RESOURCES__
  42. #include <Resources.h>
  43. #endif
  44.  
  45. #ifndef __OSUTILS__
  46. #include <OSUtils.h>
  47. #endif
  48.  
  49. #ifndef __SCRIPT__
  50. #include <Script.h>
  51. #endif
  52.  
  53. #ifndef __STRINGUTILS__
  54. #include "StringUtils.h"
  55. #endif
  56.  
  57. #ifndef __UTILITIES__
  58. #include "Utilities.h"
  59. #endif
  60.  
  61. #ifndef __TEXTEDIT__
  62. #include <TextEdit.h>
  63. #endif
  64.  
  65.  
  66.  
  67. /*****************************************************************************/
  68.  
  69.  
  70.  
  71. void            DebugWindow(Str255 str);
  72.  
  73. static pascal long        ButtonsCtl(short varCode, ControlHandle ctl, short msg, long parm);
  74. void                    InitButtonsCtl(short viewID);
  75. Boolean                    IsButtonsCtl(ControlHandle ctl);
  76. static pascal void        NoRect(GrafVerb verb, Rect *r);
  77. static void                GetRects(Rect rct, Rect *tr, Rect *r);
  78.  
  79. #ifdef powerc
  80. #pragma options align=mac68k
  81. #endif
  82. typedef struct cdefRsrcJMP {
  83.     long    jsrInst;
  84.     long    mmemInst;
  85.     short    mregInst;
  86.     short    beqInst;
  87.     short    jmpInst;
  88.     long    jmpAddress;
  89. } cdefRsrcJMP;
  90. typedef cdefRsrcJMP *cdefRsrcJMPPtr, **cdefRsrcJMPHndl;
  91. #ifdef powerc
  92. #pragma options align=reset
  93. #endif
  94.  
  95. static cdefRsrcJMPHndl    gButtonsCDEF;
  96.  
  97.  
  98.  
  99. /*****************************************************************************/
  100. /*****************************************************************************/
  101.  
  102. #ifdef applec
  103. #pragma segment ButtonsControl
  104. #endif
  105.  
  106. /*****************************************************************************/
  107. /*****************************************************************************/
  108.  
  109.  
  110.  
  111. static pascal long    ButtonsCtl(short varCode, ControlHandle ctl, short msg, long parm)
  112. {
  113.     Rect        rct, r, tr;
  114.     WindowPtr    ww;
  115.     short        txFont, txSize, txMode, ascent, i, dev;
  116.     Style        txFace;
  117.     FontInfo    finfo;
  118.     Str255        str;
  119.     QDProcs        qdp;
  120.     QDProcsPtr    oldqdp;
  121.     RgnHandle    oldClip, bwClip, clClip;
  122.     RGBColor    oldrgb;
  123.  
  124.     static QDRectUPP    qdrupp;
  125.     static RGBColor        grayrgb  = {0x8000, 0x8000, 0x8000};
  126.  
  127.     rct = (*ctl)->contrlRect;
  128.     GetPort(&ww);
  129.  
  130.     switch (msg) {
  131.  
  132.         case drawCntl:
  133.             txFont = ww->txFont;
  134.             txSize = ww->txSize;
  135.             txFace = ww->txFace;
  136.             txMode = ww->txMode;
  137.             GetFontInfo(&finfo);
  138.             ascent = (finfo.ascent - finfo.descent) / 2;
  139.             if (!(varCode & 0x08)) {
  140.                 TextFont(systemFont);
  141.                 TextFace(normal);
  142.                 TextSize(0);
  143.                 ascent = 4;
  144.             }
  145.             switch (varCode & 0x07) {
  146.                 case checkBoxProc:
  147.                 case radioButProc:
  148.                     GetRects(rct, &tr, &r);
  149.                     GetFontInfo(&finfo);
  150.                     tr.bottom = tr.top + (tr.bottom - tr.top + 1) / 2;
  151.                     i = (finfo.ascent + finfo.descent);
  152.                     tr.bottom += (i / 2);
  153.                     tr.top     = tr.bottom - i;
  154.                     pcpy(str, (*ctl)->contrlTitle);
  155.  
  156.                     oldqdp = ww->grafProcs;
  157.                     if (oldqdp)
  158.                         BlockMove(oldqdp, &qdp, sizeof(QDProcs));
  159.                     else
  160.                         SetStdProcs(&qdp);
  161.                     if (!qdrupp) {
  162. #if USES68KINLINES
  163.                         qdrupp = (QDRectUPP)NoRect;
  164. #else
  165.                         qdrupp = NewQDRectProc(NoRect);
  166. #endif
  167.                     }
  168.                     qdp.rectProc = qdrupp;
  169.                     ww->grafProcs = &qdp;
  170.  
  171.                     TextMode(srcOr);
  172.                     TETextBox(str + 1, str[0], &tr, teFlushDefault);
  173.                     TextMode(txMode);
  174.                     ww->grafProcs = oldqdp;
  175.                     GetClip(oldClip = NewRgn());
  176.                     if ((*ctl)->contrlHilite == 255) {
  177.                         bwClip = LocalScreenDepthRegion(1);
  178.                         clClip = LocalScreenDepthRegion(4);
  179.                         DiffRgn(bwClip, clClip, bwClip);
  180.                         SectRgn(bwClip, oldClip, bwClip);
  181.                         SectRgn(clClip, oldClip, clClip);
  182.                     }
  183.                     else {
  184.                         CopyRgn(oldClip, bwClip = NewRgn());
  185.                         clClip = NewRgn();
  186.                     }
  187.                     for (dev = 0; dev < 2; ++dev) {
  188.                         if (!dev) {
  189.                             if (EmptyRgn(bwClip)) continue;
  190.                             SetClip(bwClip);
  191.                             if ((*ctl)->contrlHilite == 255) PenPat((ConstPatternParam)&qd.gray);
  192.                         }
  193.                         if (dev) {
  194.                             if (EmptyRgn(clClip)) continue;
  195.                             SetClip(clClip);
  196.                             if ((*ctl)->contrlHilite == 255) {
  197.                                 GetForeColor(&oldrgb);
  198.                                 RGBForeColor(&grayrgb);
  199.                             }
  200.                         }
  201.                         if ((*ctl)->contrlHilite == 0x01) PenSize(2, 2);
  202.                         if ((varCode & 0x07) == radioButProc) {
  203.                             EraseOval(&r);
  204.                             FrameOval(&r);
  205.                             PenSize(1, 1);
  206.                             if ((*ctl)->contrlValue) {
  207.                                 InsetRect(&r, 3, 3);
  208.                                 PaintOval(&r);
  209.                                 InsetRect(&r, -3, -3);
  210.                             }
  211.                         }
  212.                         else {
  213.                             EraseRect(&r);
  214.                             FrameRect(&r);
  215.                             PenSize(1, 1);
  216.                             if ((*ctl)->contrlValue) {
  217.                                 MoveTo(r.left,      r.top);
  218.                                 LineTo(r.right - 1, r.bottom - 1);
  219.                                 MoveTo(r.right - 1, r.top);
  220.                                 LineTo(r.left,      r.bottom - 1);
  221.                             }
  222.                         }
  223.                         if (dev)
  224.                             if ((*ctl)->contrlHilite == 255)
  225.                                 RGBForeColor(&oldrgb);
  226.                         PenNormal();
  227.                     }
  228.                     SetClip(oldClip);
  229.                     DisposeRgn(oldClip);
  230.                     DisposeRgn(bwClip);
  231.                     DisposeRgn(clClip);
  232.                     break;
  233.             }
  234.             break;
  235.  
  236.         case testCntl:
  237.             if ((*ctl)->contrlHilite == 255) return(0);
  238.                 /* Control disabled, so no click.  We probably don't get called in this case. */
  239.             return(PtInRect(*(Point *)&parm, &rct));
  240.             break;
  241.  
  242.         case calcCRgns:
  243.         case calcCntlRgn:
  244.         case calcThumbRgn:
  245.             if (msg == calcCRgns) parm &= 0x00FFFFFF;
  246.             RectRgn((RgnHandle)parm, &rct);
  247.             if (msg != calcCRgns) return(1);
  248.             break;
  249.  
  250.         case initCntl:
  251.             break;
  252.  
  253.         case dispCntl:
  254.             break;
  255.  
  256.         case posCntl:
  257.             break;
  258.  
  259.         case thumbCntl:
  260.             break;
  261.  
  262.         case dragCntl:
  263.             break;
  264.  
  265.         case autoTrack:
  266.             break;
  267.     }
  268.  
  269.     return(0);
  270. }
  271.  
  272.  
  273.  
  274. /*****************************************************************************/
  275.  
  276.  
  277.  
  278. void    InitButtonsCtl(short viewID)
  279. {
  280.     static ControlDefUPP    cdefupp;
  281.  
  282.     if (!gButtonsCDEF) {
  283.         gButtonsCDEF = (cdefRsrcJMPHndl)GetResource('CDEF', (viewID / 16));
  284.         if (gButtonsCDEF) {
  285.             if (!cdefupp) {
  286.                 cdefupp = NewControlDefProc(ButtonsCtl);
  287.             }
  288.             (*gButtonsCDEF)->jmpAddress = (long)cdefupp;
  289.             if (TrapExists(_HWPriv))
  290.                 FlushInstructionCache();
  291.                     /* Make sure that instruction caches don't kill us. */
  292.         }
  293.     }
  294. }
  295.  
  296.  
  297.  
  298. /*****************************************************************************/
  299.  
  300.  
  301.  
  302. Boolean    IsButtonsCtl(ControlHandle ctl)
  303. {
  304.     if (ctl)
  305.         if (StripAddress((*ctl)->contrlDefProc) == StripAddress(gButtonsCDEF))
  306.             return(true);
  307.                 /* The handle may be locked, which means that the hi-bit
  308.                 ** may be on, thus invalidating the compare.  Dereference the
  309.                 ** handles to get rid of this possibility. */
  310.     return(false);
  311. }
  312.  
  313.  
  314.  
  315. /*****************************************************************************/
  316.  
  317.  
  318.  
  319. static pascal void    NoRect(GrafVerb verb, Rect *r)
  320. {
  321. #ifndef __MWERKS__
  322. #pragma unused (verb, r)
  323. #endif
  324. }
  325.  
  326.  
  327.  
  328. /*****************************************************************************/
  329.  
  330.  
  331.  
  332. static void    GetRects(Rect rct, Rect *tr, Rect *r)
  333. {
  334.     *tr = *r = rct;            /* Return text rect and indicator rect. */
  335.     r->top  = (r->top + (r->bottom - r->top + 1) / 2);
  336.     r->top -= 6;
  337.     r->bottom = r->top + 12;
  338.     if (!GetSysDirection()) {
  339.         r->left  += 2;
  340.         r->right  = r->left + 12;
  341.         tr->left  += 17;
  342.     }
  343.     else {
  344.         r->right -= 2;
  345.         r->left   = r->right - 12;
  346.         tr->right -= 17;
  347.     }
  348. }
  349.  
  350.  
  351.  
  352.